package com.acme.bankapp.domain.bank;

import com.acme.bankapp.exception.bank.AccountOperationException;
import com.acme.bankapp.exception.bank.WithdrawException;


/**
 * Abstract implementation of Account, implementing main functionality.
 * Withdraw(...) method is based on abstract method maximumAmountToWithdraw().
 *
 */
public abstract class AbstractAccount implements Account {

    private double balance;

    /**
     * Creates Account with amount on balance
     * @param amount initial amount
     */
    public AbstractAccount(final double amount) {

        this.balance = amount;
    }


    /**
     * {@inheritDoc}
     */
    public double getBalance() {
        return balance;
    }

    protected void setBalance(double balance) {
        this.balance = balance;
    }
    /**
     * {@inheritDoc}
     */
    public double deposit(final double amount) throws AccountOperationException{
        assert amount >= 0 : "Amount should be positive!";
        if(amount < 0){
            throw new AccountOperationException("Amount should be positive!");
        }
        balance += amount;
        return balance;
    }
    /**
     * {@inheritDoc}
     */
    public double withdraw(final double amount) throws AccountOperationException {
        assert amount >= 0 : "Amount should be positive!";
        if(amount < 0){
            throw new AccountOperationException("Amount should be positive!");
        }
        // we rely on maxAmount method to check if operation is allowed
        if(amount > maximumAmountToWithdraw()){
            throw new WithdrawException(String.format("You tried to withdraw %s but you can only withdraw %s",amount,maximumAmountToWithdraw()));
        }else{
            balance -= amount;
            return balance;
        }
    }
    /**
     * {@inheritDoc}
     */
    public abstract double maximumAmountToWithdraw();

}
